#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WebServer.h>
#include <FS.h>

ESP8266WiFiMulti wifiMulti;                  // 建立 ESP8266WiFiMulti 对象
ESP8266WebServer esp8266_server(80);         // 建立网络服务器对象，监听端口 80

void setup() {
  Serial.begin(9600);                        // 启动串口通讯
  pinMode(LED_BUILTIN, OUTPUT);              // 初始化板载 LED 引脚为 OUTPUT
  digitalWrite(LED_BUILTIN, LOW);           // 初始化 LED 引脚状态

  // 添加 WiFi 账号和密码
  wifiMulti.addAP("XX05856", "xx123456");

  Serial.println("Connecting to WiFi...");
  int i = 0;
  while (wifiMulti.run() != WL_CONNECTED) {  // 尝试进行 WiFi 连接
    delay(1000);
    Serial.print(".");                       // 动态显示连接进度
    if (++i > 10) {                          // 如果超过 10 秒未连接成功，重启设备
      Serial.println("\nFailed to connect to WiFi. Restarting...");
      ESP.restart();
    }
  }

  // WiFi 连接成功后输出信息
  Serial.println("\nWiFi Connected!");
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  // 启动 SPIFFS 文件系统
  if (!SPIFFS.begin()) {
    Serial.println("SPIFFS Failed to Start. Restarting...");
    ESP.restart();                           // 如果 SPIFFS 初始化失败，重启设备
  }
  Serial.println("SPIFFS Started.");

  // 设置 HTTP 请求处理函数
  esp8266_server.on("/setLED", handleLED);   // 处理 /setLED 请求
  esp8266_server.onNotFound(handleUserRequest); // 处理其他请求

  esp8266_server.begin();                    // 启动 HTTP 服务
  Serial.println("HTTP Server Started.");
}

void loop() {
  esp8266_server.handleClient();             // 处理客户端请求
}

// 处理 /setLED 请求
void handleLED() {
  String ledState = "OFF";
  String LED_State = esp8266_server.arg("LEDstate"); // 获取前端传来的参数
  Serial.println("LED State: " + LED_State);

  if (LED_State == "1") {
    digitalWrite(LED_BUILTIN, HIGH);         // 点亮 LED
    ledState = "ON";
  } else {
    digitalWrite(LED_BUILTIN, LOW);          // 熄灭 LED
    ledState = "OFF";
  }

  esp8266_server.send(200, "text/plain", ledState); // 返回响应
}

// 处理用户浏览器的 HTTP 访问
void handleUserRequest() {
  String reqResource = esp8266_server.uri(); // 获取用户请求资源
  Serial.println("Requested Resource: " + reqResource);

  if (reqResource.endsWith("/")) {           // 如果访问地址以 "/" 结尾
    reqResource = "/index.html";             // 默认返回 index.html
  }

  if (!handleFileRead(reqResource)) {        // 如果资源未找到
    esp8266_server.send(404, "text/plain", "404 Not Found");
  }
}

// 处理文件读取
bool handleFileRead(String resource) {
  if (!SPIFFS.exists(resource)) {            // 如果文件不存在
    return false;
  }

  File file = SPIFFS.open(resource, "r");    // 打开文件
  esp8266_server.streamFile(file, getContentType(resource)); // 发送文件
  file.close();                              // 关闭文件
  return true;
}

// 获取文件类型
String getContentType(String filename) {
  static const struct {
    const char *extension;
    const char *contentType;
  } contentTypes[] = {
    {".htm", "text/html"},
    {".html", "text/html"},
    {".css", "text/css"},
    {".js", "application/javascript"},
    {".png", "image/png"},
    {".gif", "image/gif"},
    {".jpg", "image/jpeg"},
    {".ico", "image/x-icon"},
    {".xml", "text/xml"},
    {".pdf", "application/x-pdf"},
    {".zip", "application/x-zip"},
    {".gz", "application/x-gzip"}
  };

  for (const auto &type : contentTypes) {
    if (filename.endsWith(type.extension)) {
      return type.contentType;
    }
  }
  return "text/plain";
}
